package com.spring.format.code.generation.biz.impl;

import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.spring.format.code.generation.biz.ITableBiz;
import com.spring.format.code.generation.constants.Constants;
import com.spring.format.code.generation.constants.FileNameEnumType;
import com.spring.format.code.generation.mybatis.po.TableFieldPO;
import com.spring.format.code.generation.mybatis.po.TablePO;
import com.spring.format.code.generation.mybatis.vo.CreateFileVO;
import com.spring.format.code.generation.mybatis.vo.JavaAttributeVO;
import com.spring.format.code.generation.service.ITableService;
import com.spring.format.code.generation.util.FieldUtil;
import com.spring.format.code.generation.util.FilePathUtil;
import com.spring.format.code.generation.util.FileUtil;
import com.spring.format.code.generation.util.NameUtil;
import com.spring.format.code.generation.util.PropertiesUtil;
import com.spring.format.code.generation.util.TableUtil;
import com.spring.format.code.generation.util.file.CommonActionFileUtil;
import com.spring.format.code.generation.util.file.CommonBizApiFileUtil;
import com.spring.format.code.generation.util.file.CommonBizFileUtil;
import com.spring.format.code.generation.util.file.CommonControllerFileUtil;
import com.spring.format.code.generation.util.file.CommonDaoFileUtil;
import com.spring.format.code.generation.util.file.CommonFormFileUtil;
import com.spring.format.code.generation.util.file.CommonMyBatisFileUtil;
import com.spring.format.code.generation.util.file.CommonPOFileUtil;
import com.spring.format.code.generation.util.file.CommonServiceApiFileUtil;
import com.spring.format.code.generation.util.file.CommonServiceFileUtil;
import com.spring.format.code.generation.util.file.CommonVOFileUtil;
import com.spring.format.code.generation.util.file.CommonWebServiceApiFileUtil;
import com.spring.format.code.generation.util.file.CommonWebServiceFileUtil;
import com.spring.format.code.generation.util.file.FormFileUtil;
import com.spring.format.code.generation.util.file.POFileUtil;
import com.spring.format.code.generation.util.file.ShopActionFileUtil;
import com.spring.format.code.generation.util.file.ShopBizApiFileUtil;
import com.spring.format.code.generation.util.file.ShopBizFileUtil;
import com.spring.format.code.generation.util.file.ShopDaoFileUtil;
import com.spring.format.code.generation.util.file.ShopMyBatisFileUtil;
import com.spring.format.code.generation.util.file.ShopServiceApiFileUtil;
import com.spring.format.code.generation.util.file.ShopServiceFileUtil;
import com.spring.format.code.generation.util.file.ShopWebServiceApiFileUtil;
import com.spring.format.code.generation.util.file.ShopWebServiceFileUtil;
import com.spring.format.code.generation.util.file.VOFileUtil;

/**
 * 逻辑业务层 代码实现类
 * 
 * @author lenovo
 *
 */
@Service("tableBizImpl")
public class TableBizImpl implements ITableBiz {
	/**
	 * 日志
	 */
	private Logger logger = LoggerFactory.getLogger(this.getClass());

	@Resource(name = "tableServiceImpl")
	private ITableService tableServiceImpl;

	/** 开始生成文件 */
	public void createFiles() {
		// 数据库实例名称
		String mysqlInstance = String.valueOf(PropertiesUtil.getValue(Constants.MYSQL_INSTANCE));
		logger.debug("数据库实例 mysqlInstance={}", mysqlInstance);
		// 查询数据库表集合
		List<TablePO> tableList = this.tableServiceImpl.queryTableList(mysqlInstance);
		List<TableFieldPO> myBatisFieldList = null;
		for (TablePO tablePO : tableList) {
			CreateFileVO fileVO = new CreateFileVO();
			fileVO.setTablePO(tablePO);
			// 有配置
			if (!TableUtil.tableNameList.isEmpty()) {
				if (TableUtil.tableNameList.indexOf(tablePO.getTable_name()) < 0) {
					logger.debug("没有配置table_name={}", tablePO.getTable_name());
					continue;
				}
			}
			myBatisFieldList = this.tableServiceImpl.queryTableFieldList(mysqlInstance, tablePO.getTable_name());
			// 去除多余字段（如basePO,baseForm里面存在的字段），增加需要的枚举字段
			fileVO.setAttrVOList(mysqlPO2JavaAttributeVO(myBatisFieldList));
			logger.debug("生成表{}数据", tablePO.getTable_name());

			if ("common".equalsIgnoreCase(Constants.CREATE_CODE_TYPE)) {
				// 生成 po文件
				createCommonPOFile(fileVO);
				// // 生成 vo文件
				createCommonVOFile(fileVO);
				// // 生成 form 文件
				createCommonFormFile(fileVO);
				// // 生成dao文件
				createCommonDaoFile(fileVO);
				// // 生成 mapper 文件
				createCommonMybatisFile(fileVO);
				// // 生成service api 文件
				createCommonServiceApiFile(fileVO);
				// // 生成service 文件
				createCommonServiceFile(fileVO);
				// // 生成biz api 文件
				createCommonBizApiFile(fileVO);
				// // 生成biz 文件
				createCommonBizFile(fileVO);
				// 生成web端service api文件
				createCommonWebServiceApi(fileVO);
				// // 生成web端service 实现类 文件
				createCommonWebService(fileVO);
				// // 生成Action
				createCommonActionFile(fileVO);
				// // 生成controller
				createCommonControllerFile(fileVO);

			} else if ("shop".equalsIgnoreCase(Constants.CREATE_CODE_TYPE)) {
				// 生成 po文件
				createPOFile(fileVO);
				// // 生成 vo文件
				createVOFile(fileVO);
				// // 生成 form 文件
				createFormFile(fileVO);
				// // 生成dao文件
				createShopDaoFile(fileVO);
				// // 生成 mapper 文件
				createShopMybatisFile(fileVO);
				// // 生成service api 文件
				createShopServiceApiFile(fileVO);
				// // 生成service 文件
				createShopServiceFile(fileVO);
				// // 生成biz api 文件
				createShopBizApiFile(fileVO);
				// // 生成biz 文件
				createShopBizFile(fileVO);
				// 生成web端service api文件
				createShopWebServiceApi(fileVO);
				// // 生成web端service 实现类 文件
				createShopWebService(fileVO);
				// // 生成Action
				createShopActionFile(fileVO);
				// // 生成controller
				// createControllerFile(tablePO);
			}

		}
	}

	/** 生成po文件 ***/
	private void createPOFile(CreateFileVO fileVO) {
		// 生成文件参数
		fileVO.setContent(POFileUtil.content(fileVO));
		fileVO.setFilePath(FilePathUtil.createFilePath(Constants.PATH_PO));
		fileVO.setFileName(FilePathUtil.createJavaFileName(fileVO.getTablePO(), FileNameEnumType.PO_NAME));
		// 生成文件
		FileUtil.createFile(fileVO);
	}

	/** 生成vo文件 ***/
	private void createVOFile(CreateFileVO fileVO) {
		// 生成文件参数
		fileVO.setContent(VOFileUtil.content(fileVO));
		fileVO.setFilePath(FilePathUtil.createFilePath(Constants.PATH_VO));
		fileVO.setFileName(FilePathUtil.createJavaFileName(fileVO.getTablePO(), FileNameEnumType.VO_NAME));
		// 生成文件
		FileUtil.createFile(fileVO);
	}

	/** 生成form 文件 ***/
	private void createFormFile(CreateFileVO fileVO) {
		// 生成文件参数
		fileVO.setContent(FormFileUtil.content(fileVO));
		fileVO.setFilePath(FilePathUtil.createFilePath(Constants.PATH_FORM));
		fileVO.setFileName(FilePathUtil.createJavaFileName(fileVO.getTablePO(), FileNameEnumType.FORM_NAME));
		// 生成文件
		FileUtil.createFile(fileVO);
	}

	/** 生成 dao 文件 **/
	private void createShopDaoFile(CreateFileVO fileVO) {
		// 生成文件参数
		fileVO.setContent(ShopDaoFileUtil.content(fileVO));
		fileVO.setFilePath(FilePathUtil.createFilePath(Constants.PATH_DAO_API));
		fileVO.setFileName(FilePathUtil.createJavaFileName(fileVO.getTablePO(), FileNameEnumType.DAO_API_NAME));
		// 生成文件
		FileUtil.createFile(fileVO);
	}

	/** 生成 mybatis 文件 **/
	private void createShopMybatisFile(CreateFileVO fileVO) {
		// 生成文件参数
		fileVO.setContent(ShopMyBatisFileUtil.content(fileVO));
		fileVO.setFilePath(FilePathUtil.createFilePath(Constants.PATH_MAPPER));
		fileVO.setFileName(FilePathUtil.createXmlFileName(fileVO.getTablePO(), FileNameEnumType.MAPPER_NAME));
		// 生成文件
		FileUtil.createFile(fileVO);
	}

	/** 生成service api 文件 ***/
	private void createShopServiceApiFile(CreateFileVO fileVO) {
		// 生成文件参数
		fileVO.setContent(ShopServiceApiFileUtil.content(fileVO));
		fileVO.setFilePath(FilePathUtil.createFilePath(Constants.PATH_SERVICE_API));
		fileVO.setFileName(FilePathUtil.createJavaFileName(fileVO.getTablePO(), FileNameEnumType.SERVICE_API_NAME));
		// 生成文件
		FileUtil.createFile(fileVO);
	}

	/** 生成service 文件 ***/
	private void createShopServiceFile(CreateFileVO fileVO) {
		// 生成文件参数
		fileVO.setContent(ShopServiceFileUtil.content(fileVO));
		fileVO.setFilePath(FilePathUtil.createFilePath(Constants.PATH_SERVICE));
		fileVO.setFileName(FilePathUtil.createJavaFileName(fileVO.getTablePO(), FileNameEnumType.SERVICE_NAME));
		// 生成文件
		FileUtil.createFile(fileVO);
	}

	/** 生成biz api 文件 ***/
	private void createShopBizApiFile(CreateFileVO fileVO) {
		// 生成文件参数
		fileVO.setContent(ShopBizApiFileUtil.content(fileVO));
		fileVO.setFilePath(FilePathUtil.createFilePath(Constants.PATH_BIZ_API));
		fileVO.setFileName(FilePathUtil.createJavaFileName(fileVO.getTablePO(), FileNameEnumType.BIZ_API_NAME));
		// 生成文件
		FileUtil.createFile(fileVO);
	}

	/** 生成biz 文件 ***/
	private void createShopBizFile(CreateFileVO fileVO) {
		// 生成文件参数
		fileVO.setContent(ShopBizFileUtil.content(fileVO));
		fileVO.setFilePath(FilePathUtil.createFilePath(Constants.PATH_BIZ));
		fileVO.setFileName(FilePathUtil.createJavaFileName(fileVO.getTablePO(), FileNameEnumType.BIZ_NAME));
		// 生成文件
		FileUtil.createFile(fileVO);
	}

	/** 生成web端service api 文件 ***/
	private void createShopWebServiceApi(CreateFileVO fileVO) {
		// 生成文件参数
		fileVO.setContent(ShopWebServiceApiFileUtil.content(fileVO));
		fileVO.setFilePath(FilePathUtil.createFilePath(Constants.PATH_WEB_API_SERVICE));
		fileVO.setFileName(FilePathUtil.createJavaFileName(fileVO.getTablePO(), FileNameEnumType.WEB_SERVICE_API_NAME));
		// 生成文件
		FileUtil.createFile(fileVO);
	}

	/** 生成web端service 实现类 文件 ***/
	private void createShopWebService(CreateFileVO fileVO) {
		// 生成文件参数
		fileVO.setContent(ShopWebServiceFileUtil.content(fileVO));
		fileVO.setFilePath(FilePathUtil.createFilePath(Constants.PATH_WEB_SERVICE));
		fileVO.setFileName(FilePathUtil.createJavaFileName(fileVO.getTablePO(), FileNameEnumType.WEB_SERVICE_NAME));
		// 生成文件
		FileUtil.createFile(fileVO);
	}

	/** 生成action 文件 ***/
	private void createShopActionFile(CreateFileVO fileVO) {
		// 生成文件参数
		fileVO.setContent(ShopActionFileUtil.content(fileVO));
		fileVO.setFilePath(FilePathUtil.createFilePath(Constants.PATH_ACTION));
		fileVO.setFileName(FilePathUtil.createJavaFileName(fileVO.getTablePO(), FileNameEnumType.ACTION_NAME));
		// 生成文件
		FileUtil.createFile(fileVO);
	}

	// /** 生成controller 文件 ***/
	// private boolean createControllerFile(TablePO tablePO) {
	// // 生成文件内容
	// String content = ControllerFileUtil.content(tablePO, null);
	// // 生成文件
	// String filePath = PropertiesUtil.getValue(Constants.RELATIVE_PATH) +
	// PropertiesUtil.getValue(Constants.PACKAGE_PATH) +
	// Constants.DEFAULT_PACKAGE_PATH_CONTROLLER;
	// FileUtil.createFile(filePath,
	// NameUtil.createFileName(tablePO.getTable_name(),
	// FileNameEnumType.CONTROLLER_NAME) + ".java", content);
	//
	// return true;
	// }
	//
	// /**
	// * 加入或者替换掉 用户配置的 枚举类型的字段 如 data_status 实体类为枚举，数据库String， 需要将 String 替换为枚举类
	// * MDataStatusType 同时去掉 BasePO 里面已经存在的字段
	// * ***/
	// private List<TableFieldPO> enumFieldAddAndRemoveBaseHasField(final
	// List<TableFieldPO> fieldList) {
	// List<TableFieldPO> fieldListNew = new ArrayList<>();
	// // 增加需要的枚举字段
	// Map<String, MEnumVO> enumField = PropertiesUtil.getEnumField();
	// // 去除多余的字段
	// Set<String> fieldSet = PropertiesUtil.getHasExitsField();
	// fieldList.forEach(field -> {
	// if (!fieldSet.contains(field.getColumn_name())) {
	//
	// MEnumVO enumVO = enumField.get(field.getColumn_name());
	// if (null != enumVO) {
	// // 将数据库类型，替换为枚举类
	// field.setNeedImport(true);
	// field.setColumn_type(enumVO.getClass_name());
	// field.setClass_path(enumVO.getPath());
	//
	// }
	// fieldListNew.add(field);
	// }
	// }) ;
	//
	// return fieldListNew;
	// }
	/**
	 * 数据库字段类，转换为java类
	 * 
	 * @param fieldList
	 * @return
	 */
	private List<JavaAttributeVO> mysqlPO2JavaAttributeVO(final List<TableFieldPO> fieldList) {
		List<JavaAttributeVO> attrList = new ArrayList<>(fieldList.size());
		fieldList.forEach(field -> {
			JavaAttributeVO attrVO = new JavaAttributeVO();
			// mysql属性
			attrVO.setTableCatalog(field.getTable_catalog());
			attrVO.setTableSchema(field.getTable_schema());
			attrVO.setTableName(field.getTable_name());
			attrVO.setColumnName(field.getColumn_name());
			attrVO.setOrdinalPosition(field.getOrdinal_position());
			attrVO.setColunmDefault(field.getColunm_default());
			attrVO.setIsNullable(field.getIs_nullable());
			attrVO.setDataType(field.getData_type());
			attrVO.setCharacterMaxinumLength(field.getCharacter_maxinum_length());
			attrVO.setCharacterOctetLength(field.getCharacter_octet_length());
			attrVO.setNumericPrecision(field.getNumeric_precision());
			attrVO.setNumericScale(field.getNumeric_scale());
			attrVO.setDatatimePrecision(field.getDatatime_precision());
			attrVO.setCharacterSetName(field.getCharacter_set_name());
			attrVO.setCollationName(field.getCollation_name());
			attrVO.setColumnType(field.getColumn_type());
			attrVO.setExtra(field.getExtra());
			attrVO.setPrivileges(field.getPrivileges());
			attrVO.setColumnComment(field.getColumn_comment());
			// java属性
			// 字段名
			attrVO.setName(NameUtil.subFieldName(field.getColumn_name()));
			// 字段属性
			attrVO.setType(FieldUtil.fieldType(field));
			// 加入集合
			attrList.add(attrVO);
		});
		return attrList;
	}

	/*********************** 公用，可塑性代码生成出 *******************************/
	/** 生成po文件 ***/
	private void createCommonPOFile(CreateFileVO fileVO) {
		// 生成文件参数
		fileVO.setContent(CommonPOFileUtil.content(fileVO));
		fileVO.setFilePath(FilePathUtil.createFilePath(Constants.PATH_PO));
		fileVO.setFileName(FilePathUtil.createJavaFileName(fileVO.getTablePO(), FileNameEnumType.PO_NAME));
		// 生成文件
		FileUtil.createFile(fileVO);
	}

	/** 生成vo文件 ***/
	private void createCommonVOFile(CreateFileVO fileVO) {
		// 生成文件参数
		fileVO.setContent(CommonVOFileUtil.content(fileVO));
		fileVO.setFilePath(FilePathUtil.createFilePath(Constants.PATH_VO));
		fileVO.setFileName(FilePathUtil.createJavaFileName(fileVO.getTablePO(), FileNameEnumType.VO_NAME));
		// 生成文件
		FileUtil.createFile(fileVO);
	}

	/** 生成form 文件 ***/
	private void createCommonFormFile(CreateFileVO fileVO) {
		// 生成文件参数
		fileVO.setContent(CommonFormFileUtil.content(fileVO));
		fileVO.setFilePath(FilePathUtil.createFilePath(Constants.PATH_FORM));
		fileVO.setFileName(FilePathUtil.createJavaFileName(fileVO.getTablePO(), FileNameEnumType.FORM_NAME));
		// 生成文件
		FileUtil.createFile(fileVO);
	}

	/** 生成service api 文件 ***/
	private void createCommonServiceApiFile(CreateFileVO fileVO) {
		// 生成文件参数
		fileVO.setContent(CommonServiceApiFileUtil.content(fileVO));
		fileVO.setFilePath(FilePathUtil.createFilePath(Constants.PATH_SERVICE_API));
		fileVO.setFileName(FilePathUtil.createJavaFileName(fileVO.getTablePO(), FileNameEnumType.SERVICE_API_NAME));
		// 生成文件
		FileUtil.createFile(fileVO);
	}

	/** 生成service 文件 ***/
	private void createCommonServiceFile(CreateFileVO fileVO) {
		// 生成文件参数
		fileVO.setContent(CommonServiceFileUtil.content(fileVO));
		fileVO.setFilePath(FilePathUtil.createFilePath(Constants.PATH_SERVICE));
		fileVO.setFileName(FilePathUtil.createJavaFileName(fileVO.getTablePO(), FileNameEnumType.SERVICE_NAME));
		// 生成文件
		FileUtil.createFile(fileVO);
	}

	/** 生成biz api 文件 ***/
	private void createCommonBizApiFile(CreateFileVO fileVO) {
		// 生成文件参数
		fileVO.setContent(CommonBizApiFileUtil.content(fileVO));
		fileVO.setFilePath(FilePathUtil.createFilePath(Constants.PATH_BIZ_API));
		fileVO.setFileName(FilePathUtil.createJavaFileName(fileVO.getTablePO(), FileNameEnumType.BIZ_API_NAME));
		// 生成文件
		FileUtil.createFile(fileVO);
	}

	/** 生成biz 文件 ***/
	private void createCommonBizFile(CreateFileVO fileVO) {
		// 生成文件参数
		fileVO.setContent(CommonBizFileUtil.content(fileVO));
		fileVO.setFilePath(FilePathUtil.createFilePath(Constants.PATH_BIZ));
		fileVO.setFileName(FilePathUtil.createJavaFileName(fileVO.getTablePO(), FileNameEnumType.BIZ_NAME));
		// 生成文件
		FileUtil.createFile(fileVO);
	}

	/** 生成web端service api 文件 ***/
	private void createCommonWebServiceApi(CreateFileVO fileVO) {
		// 生成文件参数
		fileVO.setContent(CommonWebServiceApiFileUtil.content(fileVO));
		fileVO.setFilePath(FilePathUtil.createFilePath(Constants.PATH_WEB_API_SERVICE));
		fileVO.setFileName(FilePathUtil.createJavaFileName(fileVO.getTablePO(), FileNameEnumType.WEB_SERVICE_API_NAME));
		// 生成文件
		FileUtil.createFile(fileVO);
	}

	/** 生成web端service 实现类 文件 ***/
	private void createCommonWebService(CreateFileVO fileVO) {
		// 生成文件参数
		fileVO.setContent(CommonWebServiceFileUtil.content(fileVO));
		fileVO.setFilePath(FilePathUtil.createFilePath(Constants.PATH_WEB_SERVICE));
		fileVO.setFileName(FilePathUtil.createJavaFileName(fileVO.getTablePO(), FileNameEnumType.WEB_SERVICE_NAME));
		// 生成文件
		FileUtil.createFile(fileVO);
	}

	/** 生成action 文件 ***/
	private void createCommonActionFile(CreateFileVO fileVO) {
		// 生成文件参数
		fileVO.setContent(CommonActionFileUtil.content(fileVO));
		fileVO.setFilePath(FilePathUtil.createFilePath(Constants.PATH_ACTION));
		fileVO.setFileName(FilePathUtil.createJavaFileName(fileVO.getTablePO(), FileNameEnumType.ACTION_NAME));
		// 生成文件
		FileUtil.createFile(fileVO);
	}

	/** 生成 dao 文件 **/
	private void createCommonDaoFile(CreateFileVO fileVO) {
		// 生成文件参数
		fileVO.setContent(CommonDaoFileUtil.content(fileVO));
		fileVO.setFilePath(FilePathUtil.createFilePath(Constants.PATH_DAO_API));
		fileVO.setFileName(FilePathUtil.createJavaFileName(fileVO.getTablePO(), FileNameEnumType.DAO_API_NAME));
		// 生成文件
		FileUtil.createFile(fileVO);
	}

	/** 生成 mybatis 文件 **/
	private void createCommonMybatisFile(CreateFileVO fileVO) {
		// 生成文件参数
		fileVO.setContent(CommonMyBatisFileUtil.content(fileVO));
		fileVO.setFilePath(FilePathUtil.createFilePath(Constants.PATH_MAPPER));
		fileVO.setFileName(FilePathUtil.createXmlFileName(fileVO.getTablePO(), FileNameEnumType.MAPPER_NAME));
		// 生成文件
		FileUtil.createFile(fileVO);
	}

	/** 生成controller 文件 ***/
	private void createCommonControllerFile(CreateFileVO fileVO) {
		// 生成文件参数
		fileVO.setContent(CommonControllerFileUtil.content(fileVO));
		fileVO.setFilePath(FilePathUtil.createFilePath(Constants.PATH_CONTROLLER));
		fileVO.setFileName(FilePathUtil.createJavaFileName(fileVO.getTablePO(), FileNameEnumType.CONTROLLER_NAME));
		// 生成文件
		FileUtil.createFile(fileVO);
	}

	public static void main(String[] args) {
		System.out.println(new Date(Long.valueOf("1551974400000")));
		System.out.println(new Date(Long.valueOf("1552060800000")));
	}
}
